home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / ULARN.ARJ / ULARN.TAR / ularn / display.c < prev    next >
C/C++ Source or Header  |  1989-10-25  |  13KB  |  626 lines

  1. /*    display.c */
  2. #include "header.h"
  3.  
  4. #define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c))
  5.  
  6. static int minx,maxx,miny,maxy,k,m;
  7. static char bot1f=0,bot2f=0,bot3f=0;
  8. char always=0;
  9.  
  10. /*
  11.     bottomline()
  12.  
  13.     for the bottom line of the display
  14.  */
  15. bottomline()
  16. {    
  17.     recalc();    
  18.     bot1f=1;    
  19. }
  20. bottomhp()
  21. {    
  22.     bot2f=1;    
  23. }
  24. bottomspell()
  25. {    
  26.     bot3f=1;    
  27. }
  28. bottomdo()
  29. {
  30.     if (bot1f) { 
  31.         bot3f=bot1f=bot2f=0; 
  32.         bot_linex(); 
  33.         return; 
  34.     }
  35.     if (bot2f) { 
  36.         bot2f=0; 
  37.         bot_hpx(); 
  38.     }
  39.     if (bot3f) { 
  40.         bot3f=0; 
  41.         bot_spellx(); 
  42.     }
  43. }
  44.  
  45. bot_linex()
  46. {
  47.     register int i;
  48.     if (cbak[SPELLS] <= -50 || (always)) {
  49.         cursor( 1,18);
  50.         if (c[SPELLMAX]>99)  
  51.             lprintf("Spells:%3d(%3d)", c[SPELLS],c[SPELLMAX]);
  52.         else 
  53.             lprintf("Spells:%3d(%2d) ",c[SPELLS],c[SPELLMAX]);
  54.         lprintf(" AC: %-3d  WC: %-3d  Level",c[AC],c[WCLASS]);
  55.         if (c[LEVEL]>99) 
  56.             lprintf("%3d",c[LEVEL]);
  57.         else 
  58.             lprintf(" %-2d",c[LEVEL]);
  59.         lprintf(" Exp: %-9d %s\n",c[EXPERIENCE],class[c[LEVEL]-1]);
  60.         lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ",
  61.             c[HP],c[HPMAX],c[STRENGTH]+c[STREXTRA],
  62.             c[INTELLIGENCE]);
  63.         lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:",
  64.             c[WISDOM],c[CONSTITUTION],c[DEXTERITY],c[CHARISMA]);
  65.  
  66.         if ((level==0) || (wizard))  
  67.             c[TELEFLAG]=0;
  68.         if (c[TELEFLAG])  
  69.             lprcat(" ?");  
  70.         else  
  71.             lprcat(levelname[level]);
  72.         lprintf("  Gold: %-6d",c[GOLD]);
  73.         always=1;  
  74.         botside();
  75.         c[TMP] = c[STRENGTH]+c[STREXTRA];
  76.         for (i=0; i<100; i++) cbak[i]=c[i];
  77.         return;
  78.     }
  79.  
  80.     botsub(makecode(SPELLS,8,18),"%3d");
  81.     if (c[SPELLMAX]>99)  
  82.         botsub(makecode(SPELLMAX,12,18),"%3d)");
  83.     else 
  84.         botsub(makecode(SPELLMAX,12,18),"%2d) ");
  85.     botsub(makecode(HP,5,19),"%3d");
  86.     botsub(makecode(HPMAX,9,19),"%3d");
  87.     botsub(makecode(AC,21,18),"%-3d");
  88.     botsub(makecode(WCLASS,30,18),"%-3d");
  89.     botsub(makecode(EXPERIENCE,49,18),"%-9d");
  90.     if (c[LEVEL] != cbak[LEVEL]) { 
  91.         cursor(59,18);    
  92.         lprcat(class[c[LEVEL]-1]);  
  93.     }
  94.     if (c[LEVEL]>99) 
  95.         botsub(makecode(LEVEL,40,18),"%3d");
  96.     else 
  97.         botsub(makecode(LEVEL,40,18)," %-2d");
  98.     c[TMP] = c[STRENGTH]+c[STREXTRA];    
  99.     botsub(makecode(TMP,18,19),"%-2d");
  100.     botsub(makecode(INTELLIGENCE,25,19),"%-2d");
  101.     botsub(makecode(WISDOM,32,19),"%-2d");
  102.     botsub(makecode(CONSTITUTION,39,19),"%-2d");
  103.     botsub(makecode(DEXTERITY,46,19),"%-2d");
  104.     botsub(makecode(CHARISMA,53,19),"%-2d");
  105.     if ((level != cbak[CAVELEVEL]) || (c[TELEFLAG] != cbak[TELEFLAG])) {
  106.         if ((level==0) || (wizard))  c[TELEFLAG]=0;
  107.         cbak[TELEFLAG] = c[TELEFLAG];
  108.         cbak[CAVELEVEL] = level;    
  109.         cursor(59,19);
  110.         if (c[TELEFLAG])  
  111.             lprcat(" ?");  
  112.         else  
  113.             lprcat(levelname[level]);
  114.     }
  115.     botsub(makecode(GOLD,69,19),"%-6d");
  116.     botside();
  117. }
  118.  
  119. /*
  120.     special subroutine to update only the gold number on the bottomlines
  121.     called from ogold()
  122.  */
  123. bottomgold()
  124. {
  125.     botsub(makecode(GOLD,69,19),"%-6d");
  126. }
  127.  
  128. /*
  129.     special routine to update hp and level fields on bottom lines
  130.     called in monster.c hitplayer() and spattack()
  131.  */
  132. bot_hpx()
  133. {
  134.     if (c[EXPERIENCE] != cbak[EXPERIENCE]) {
  135.         recalc();
  136.         bot_linex();
  137.     }
  138.     else botsub(makecode(HP,5,19),"%3d");    
  139. }
  140.  
  141. /*
  142.     special routine to update number of spells called from regen()
  143.  */
  144. bot_spellx()
  145. {
  146.     botsub(makecode(SPELLS,9,18),"%2d");
  147. }
  148.  
  149. /*
  150.     common subroutine for a more economical bottomline()
  151.  */
  152. static struct bot_side_def
  153. {
  154.     int typ;
  155.     char *string;
  156. }
  157. bot_data[] =
  158. {
  159.     STEALTH,"stealth",        
  160.     UNDEADPRO,"undead pro",        
  161.     SPIRITPRO,"spirit pro",
  162.     CHARMCOUNT,"Charm",        
  163.     TIMESTOP,"Time Stop",        
  164.     HOLDMONST,"Hold Monst",
  165.     GIANTSTR,"Giant Str",    
  166.     FIRERESISTANCE,"Fire Resit", 
  167.     DEXCOUNT,"Dexterity",
  168.     STRCOUNT,"Strength",    
  169.     SCAREMONST,"Scare",            
  170.     HASTESELF,"Haste Self",
  171.     CANCELLATION,"Cancel",    
  172.     INVISIBILITY,"Invisible",    
  173.     ALTPRO,"Protect 3",
  174.     PROTECTIONTIME,"Protect 2", 
  175.     WTW,"Wall-Walk"
  176. };
  177.  
  178. botside()
  179. {
  180.     register int i,idx;
  181.  
  182.     for (i=0; i<17; i++) {
  183.         idx = bot_data[i].typ;
  184.         if ((always) || (c[idx] != cbak[idx])) {
  185.             if ((always) || (cbak[idx] == 0)) { 
  186.                 if (c[idx]) { 
  187.                     cursor(70,i+1); 
  188.                     lprcat(bot_data[i].string); 
  189.                 } 
  190.             }  
  191.             else
  192.                 if (c[idx]==0)     { 
  193.                     cursor(70,i+1); 
  194.                     lprcat("          "); 
  195.                 }
  196.             cbak[idx]=c[idx];
  197.         }
  198.     }
  199.     always=0;
  200. }
  201.  
  202. botsub(idx,str)
  203. register int idx;
  204. char *str;
  205. {
  206.     register int x,y;
  207.  
  208.     y = idx & 0xff;
  209.     x = (idx>>8) & 0xff;
  210.     idx >>= 16;
  211.     if (c[idx] != cbak[idx]) { 
  212.         cbak[idx]=c[idx];  
  213.         cursor(x,y);  
  214.         lprintf(str,c[idx]); 
  215.     }
  216. }
  217.  
  218. /*
  219.  *    subroutine to draw only a section of the screen
  220.  *    only the top section of the screen is updated.  If entire lines are being
  221.  *    drawn, then they will be cleared first.
  222.  */
  223. int d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY;    /* for limited screen drawing */
  224. draws(xmin,xmax,ymin,ymax)
  225. int xmin,xmax,ymin,ymax;
  226. {
  227.     register int i,idx;
  228.     if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */
  229.     {
  230.         if (ymin==0) cl_up(79,ymax);
  231.         else for (i=ymin; i<ymin; i++)  cl_line(1,i+1);
  232.         xmin = -1;
  233.     }
  234.     d_xmin=xmin;    
  235.     d_xmax=xmax;    
  236.     d_ymin=ymin;    
  237.     d_ymax=ymax;    /* for limited screen drawing */
  238.     drawscreen();
  239.     if (xmin<=0 && xmax==MAXX)  {
  240. /* draw stuff on right side of screen as needed*/
  241.         for (i=ymin; i<ymax; i++) {
  242.             idx = bot_data[i].typ;
  243.             if (c[idx]) {
  244.                 cursor(70,i+1); 
  245.                 lprcat(bot_data[i].string);
  246.             }
  247.             cbak[idx]=c[idx];
  248.         }
  249.     }
  250. }
  251.  
  252. /*
  253.     drawscreen()
  254.  
  255.     subroutine to redraw the whole screen as the player knows it
  256.  */
  257. char screen[MAXX][MAXY],d_flag;    /* template for the screen */
  258. drawscreen()
  259. {
  260.     register int i,j,k;
  261.  
  262.     int lastx,lasty;  /* variables used to optimize the object printing */
  263.     if (d_xmin==0 && d_xmax==MAXX && d_ymin==0 && d_ymax==MAXY) {
  264.         d_flag=1;  
  265.         clear(); /* clear the screen */
  266.     }
  267.     else {
  268.         d_flag=0;  
  269.         cursor(1,1);
  270.     }
  271.     if (d_xmin<0)
  272.         d_xmin=0; /* d_xmin=-1 means display all without bottomline */
  273.  
  274.     for (i=d_ymin; i<d_ymax; i++)
  275.         for (j=d_xmin; j<d_xmax; j++)
  276.             if (know[j][i]==0)  screen[j][i] = ' ';  
  277.             else
  278.                 if (k=mitem[j][i])  {
  279.                   if (k==MIMIC)
  280.                     screen[j][i] = 
  281.                         monstnamelist[rund(MAXMONST)];
  282.                   else
  283.                       screen[j][i] = monstnamelist[k];  
  284.                 }
  285.             else
  286.                 if ((k=item[j][i])==OWALL) 
  287.                     screen[j][i] = '#';
  288.                     else screen[j][i] = ' ';
  289.  
  290.     for (i=d_ymin; i<d_ymax; i++) {
  291.         j=d_xmin;  
  292.         while ((screen[j][i]==' ') && (j<d_xmax)) j++;
  293.         if (j >= d_xmax)  
  294.             m=d_xmin; /* don't search backwards if blank line */
  295.         else {    /* search backwards for end of line */
  296.             m=d_xmax-1;  
  297.             while ((screen[m][i]==' ') && (m>d_xmin)) --m;
  298.             if (j<=m)  cursor(j+1,i+1);  
  299.             else continue;
  300.         }
  301.         while (j <= m) {
  302.             if (j <= m-3) {
  303.                 for (k=j; k<=j+3; k++) 
  304.                     if (screen[k][i] != ' ') 
  305.                         k=1000;
  306.                 if (k < 1000) { 
  307.                     while(screen[j][i]==' ' && j<=m) 
  308.                         j++;  
  309.                     cursor(j+1,i+1); 
  310.                 }
  311.             }
  312.             lprc(screen[j++][i]);
  313.         }
  314.     }
  315.     if (boldon) setbold();        /* print out only bold objects now */
  316.  
  317.     for (lastx=lasty=127, i=d_ymin; i<d_ymax; i++)
  318.       for (j=d_xmin; j<d_xmax; j++) {
  319.         if (k=item[j][i])
  320.             if (k != OWALL)
  321.                 if ((know[j][i]) && (mitem[j][i]==0))
  322.                     if (objnamelist[k]!=' ') {
  323.                         if (lasty!=i+1 || lastx!=j)
  324.                            cursor(lastx=j+1,lasty=i+1);
  325.                         else lastx++;
  326.                         lprc(objnamelist[k]);
  327.                     }
  328.     }
  329.  
  330.     if (boldon) resetbold();  
  331.     if (d_flag)  { 
  332.         always=1; 
  333.         botside(); 
  334.         always=1; 
  335.         bot_linex(); 
  336.     }
  337.     oldx=99;
  338.     /* for limited screen drawing */
  339.     d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY; 
  340. }
  341.  
  342. /*
  343.     showcell(x,y)
  344.  
  345.     subroutine to display a cell location on the screen
  346.  */
  347. showcell(x,y)
  348. int x,y;
  349. {
  350.     register int i,j,k,m;
  351.  
  352.     if (c[BLINDCOUNT])  return;    /* see nothing if blind        */
  353.     if (c[AWARENESS]) { 
  354.         minx = x-3;    
  355.         maxx = x+3;    
  356.         miny = y-3;    
  357.         maxy = y+3; 
  358.     }
  359.     else      { 
  360.         minx = x-1;    
  361.         maxx = x+1;    
  362.         miny = y-1;    
  363.         maxy = y+1; 
  364.     }
  365.  
  366.     if (minx < 0) minx=0;        
  367.     if (maxx > MAXX-1) maxx = MAXX-1;
  368.     if (miny < 0) miny=0;        
  369.     if (maxy > MAXY-1) maxy = MAXY-1;
  370.  
  371.     for (j=miny; j<=maxy; j++)
  372.         for (m=minx; m<=maxx; m++)
  373.             if (know[m][j]==0) {
  374.                 cursor(m+1,j+1);
  375.                 x=maxx;  
  376.                 while (know[x][j]) --x;
  377.                 for (i=m; i<=x; i++) {
  378.                   if ((k=mitem[i][j]) != 0) {
  379.                     if (k==MIMIC)
  380.                         lprc(monstnamelist[rund(MAXMONST)]);
  381.                     else
  382.                     lprc(monstnamelist[k]);
  383.                   }
  384.                     else switch(k=item[i][j]) {
  385.                     case 0: 
  386.                     case OWALL:  
  387.                     case OIVTELETRAP:  
  388.                     case OTRAPARROWIV:
  389.                     case OIVDARTRAP: 
  390.                     case OIVTRAPDOOR:    
  391.                         lprc(objnamelist[k]);    
  392.                         break;
  393.  
  394.                     default: 
  395.                         if (boldon) setbold(); 
  396.                         lprc(objnamelist[k]); 
  397.                         if (boldon) resetbold();
  398.                     };
  399.                     know[i][j]=1;
  400.                 }
  401.                 m = maxx;
  402.             }
  403. }
  404.  
  405. /*
  406.     this routine shows only the spot that is given it.  the spaces around
  407.     these coordinated are not shown
  408.     used in godirect() in monster.c for missile weapons display
  409.  */
  410. show1cell(x,y)
  411. int x,y;
  412. {
  413.     if (c[BLINDCOUNT])  return;    /* see nothing if blind        */
  414.     cursor(x+1,y+1);
  415.     if ((k=mitem[x][y]) != 0)  {
  416.         if (k==MIMIC)
  417.             lprc(monstnamelist[rund(MAXMONST)]);
  418.         else
  419.             lprc(monstnamelist[k]);
  420.     }
  421.     else switch(k=item[x][y]) {
  422.     case OWALL:  
  423.     case 0:  
  424.     case OIVTELETRAP:  
  425.     case OTRAPARROWIV: 
  426.     case OIVDARTRAP: 
  427.     case OIVTRAPDOOR:    
  428.         lprc(objnamelist[k]);    
  429.         break;
  430.  
  431.     default: 
  432.         if (boldon) setbold(); 
  433.         lprc(objnamelist[k]); 
  434.         if (boldon) resetbold();
  435.     };
  436.     know[x][y]|=1;    /* we end up knowing about it */
  437. }
  438.  
  439. /*
  440.     showplayer()
  441.  
  442.     subroutine to show where the player is on the screen
  443.     cursor values start from 1 up
  444.  */
  445. showplayer()
  446. {
  447.     cursor(playerx+1,playery+1);
  448.     oldx=playerx;  
  449.     oldy=playery;
  450. }
  451.  
  452. /*
  453.     moveplayer(dir)
  454.  
  455.     subroutine to move the player from one room to another
  456.     returns 0 if can't move in that direction or hit a monster or on an object
  457.     else returns 1
  458.     nomove is set to 1 to stop the next move (inadvertent monsters hitting
  459.     players when walking into walls) if player walks off screen or into wall
  460.  */
  461. short diroffx[] = { 0,  0, 1,  0, -1,  1, -1, 1, -1 };
  462. short diroffy[] = { 0,  1, 0, -1,  0, -1, -1, 1,  1 };
  463.  
  464. moveplayer(dir)
  465. int dir;    /*    from = present room #  direction = [1-north]
  466.                 [2-east] [3-south] [4-west] [5-northeast]
  467.                 [6-northwest] [7-southeast] [8-southwest]
  468.             if direction=0, don't move--just show where he is */
  469. {
  470.     register int k,m,i,j;
  471.  
  472.     if (c[CONFUSE]) 
  473.         if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/
  474.     k = playerx + diroffx[dir];        
  475.     m = playery + diroffy[dir];
  476.  
  477.     if (k<0 || k>=MAXX || m<0 || m>=MAXY) { 
  478.         nomove=1; 
  479.         return(yrepcount = 0); 
  480.     }
  481.  
  482.     i = item[k][m];
  483.     j = mitem[k][m];
  484.  
  485.     /*    hit a wall    */
  486.     if (i==OWALL && c[WTW]==0) { 
  487.         nomove=1;  
  488.         return(yrepcount = 0); 
  489.     }        
  490.  
  491.     if (k==33 && m==MAXY-1 && level==1) {
  492.         newcavelevel(0); 
  493.         for (k=0; k<MAXX; k++) for (m=0; m<MAXY; m++)
  494.             if (item[k][m]==OENTRANCE) { 
  495.                 playerx=k; 
  496.                 playery=m; 
  497.                 positionplayer();  
  498.                 drawscreen(); 
  499.                 return(0); 
  500.             }
  501.     }
  502.     if (j>0)     {     
  503.         hitmonster(k,m);    
  504.         return(yrepcount = 0); 
  505.     } /* hit a monster*/
  506.  
  507.     lastpx = playerx;            
  508.     lastpy = playery;
  509.     playerx = k;        
  510.     playery = m;
  511.  
  512.     if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP 
  513.           && i!=OIVTRAPDOOR) 
  514.         return(yrepcount = 0);  
  515.     else return(1);
  516. }
  517.  
  518. /*
  519.  *    function to show what magic items have been discovered thus far
  520.  *    enter with -1 for just spells, 99 gives all spells in game (for when 
  521.  *    genie asks you what you want). anything else will give scrolls & potions
  522.  */
  523. static int lincount,count;
  524.  
  525. seemagic(arg)
  526. int arg;
  527. {
  528.     register int i,number;
  529.     count = lincount = 0;  
  530.     nosignal=1;
  531.  
  532.     if (arg == 99) {
  533.         number = (SPNUM+2)/3 + 4;    /* # lines needed to display */
  534.         cl_up(79,number);  
  535.         cursor(1,1);
  536.         lprcat("Availible spells are:\n\n");
  537.         for (i=0; i<SPNUM; i++) {
  538.             lprintf("%s %-20s ",spelcode[i],spelname[i]);  
  539.             seepage(); 
  540.         }
  541.         seepage();  
  542.         more();     
  543.         nosignal=0;
  544.         draws(0,MAXX,0,number);  
  545.         return;
  546.     }
  547.     if (arg== -1) /* if display spells while casting one */
  548.     {
  549.         for (number=i=0; i<SPNUM; i++) if (spelknow[i]) number++;
  550.         number = (number+2)/3 + 4;    /* # lines needed to display */
  551.         cl_up(79,number);  
  552.         cursor(1,1);
  553.     }
  554.     else {
  555.         resetscroll();  
  556.         clear();
  557.     }
  558.  
  559.     lprcat("The magic spells you have discovered thus far:\n\n");
  560.     for (i=0; i<SPNUM; i++)
  561.         if (spelknow[i]) { 
  562.             lprintf("%s %-20s ",spelcode[i],spelname[i]);  
  563.             seepage(); 
  564.         }
  565.  
  566.     if (arg== -1) {
  567.         seepage();  
  568.         more();     
  569.         nosignal=0;
  570.         draws(0,MAXX,0,number);  
  571.         return;
  572.     }
  573.  
  574.     lincount += 3;  
  575.     if (count!=0) { 
  576.         count=2;  
  577.         seepage(); 
  578.     }
  579.  
  580.     lprcat("\nThe magic scrolls you have found to date are:\n\n");
  581.     count=0;
  582.     for (i=0; i<MAXSCROLL; i++)
  583.         if (scrollname[i][0])
  584.             if (scrollname[i][1]!=' ') { 
  585.                 lprintf("%-26s",&scrollname[i][1]);  
  586.                 seepage(); 
  587.             }
  588.  
  589.     lincount += 3;  
  590.     if (count!=0) { 
  591.         count=2;  
  592.         seepage(); 
  593.     }
  594.  
  595.     lprcat("\nThe magic potions you have found to date are:\n\n");
  596.     count=0;
  597.     for (i=0; i<MAXPOTION; i++)
  598.         if (potionname[i][0])
  599.             if (potionname[i][1]!=' ') { 
  600.                 lprintf("%-26s",&potionname[i][1]);  
  601.                 seepage(); 
  602.             }
  603.  
  604.     if (lincount!=0) more();    
  605.     nosignal=0;  
  606.     setscroll();    
  607.     drawscreen();
  608. }
  609.  
  610. /*
  611.  *    subroutine to paginate the seemagic function
  612.  */
  613. seepage()
  614. {
  615.     if (++count==3) {
  616.         lincount++;    
  617.         count=0;    
  618.         lprc('\n');
  619.         if (lincount>17) {    
  620.             lincount=0;  
  621.             more();  
  622.             clear();    
  623.         }
  624.     }
  625. }
  626.